/**
 * ajax工具
 */
const AjaxUtil = {
    // Ajax请求
    requestParams: function (params) {
        // 是否需要等待
        var idx = 0;
        if (!params.wait) {
            idx = layer.load();
        }
        // 配置
        var settings = {
            url: params.url,
            type: params.type ? params.type : "POST",
            success: params.callback,
            // 失败加载函数
            error: function (jqXHR, textStatus, errorThrown) {
                console.log("ajax异常！", jqXHR, textStatus, errorThrown);
                if (params.error) {
                    params.error(jqXHR, textStatus, errorThrown);
                }
            },
            // 请求完成后最终执行参数
            complete: function (XMLHttpRequest, status) {
                //超时,status还有success,error等值的情况
                if (status == 'timeout') {

                }
            }
        }
        // 传输数据
        if (params.data !== undefined) {
            settings.data = params.data;
        }
        // 是否异步
        if (params.async !== undefined) {
            settings.async = params.async;
        }
        // 等待时间
        if (params.timeout !== undefined) {
            settings.timeout = params.timeout;
        }
        // 数据类型 eg: dataType: "json"
        if (params.dataType !== undefined) {
            settings.dataType = params.dataType;
        }
        // 特殊数据时 并且JSON.stringify(param)
        if (params.headers !== undefined) {
            settings.headers = {
                "Content-Type": "application/json"
            };
        }
        // new FormData(document.getElementById("form表单的id")) 表单数据cache，processData，contentType为false
        // 是否缓存数据
        if (params.cache !== undefined) {
            settings.cache = params.cache;
        }
        // 是否处理数据
        if (params.processData !== undefined) {
            settings.processData = params.processData;
        }
        // 是否设置内容类型
        if (params.contentType !== undefined) {
            settings.contentType = params.contentType;
        }
        $.ajax(settings).always(function () {
            if (!params.wait) {
                layer.close(idx);
            }
            // 不管结果如何总是执行
            if (params.always) {
                params.always();
            }
        });
    },
    // get请求
    getRequest: function (url, data, callback, error, always) {
        this.requestParams({
            url: url,
            data: data,
            type: "GET",
            callback: callback,
            error: error,
            always: always
        });
    },
    // post请求
    postRequest: function (url, data, callback, error, always) {
        this.requestParams({
            url: url,
            data: data,
            type: "POST",
            callback: callback,
            error: error,
            always: always
        });
    },
    // post请求
    postRequestByFormData: function (url, data, callback, error, always) {
        this.requestParams({
            url: url,
            data: data,
            type: "POST",
            cache: false,        // 不缓存数据
            processData: false,  //  告诉jquery不要处理发送的数据
            contentType: false,  //  告诉jquery不要设置content-Type请求头
            callback: callback,
            error: error,
            always: always
        });
    }
};

/**
 * url处理工具
 */
const UrlUtil = {
    /**
     * 将参数拼接到url后面
     * @param url
     * @param params
     * @returns {string}
     */
    splicingParams: function (url, params) {
        // 判断里面没有没有参数
        if (url.indexOf('?') == -1) {
            url = url + '?';
        } else {
            if (url.indexOf(url.length - 1) !== '&') {
                url = url + '&';
            }
        }
        if (params !== undefined) {
            var key = Object.keys(params);
            for (var i in key) {
                var v = params[key[i]];
                // 去除空数据
                if (v !== '' && v !== undefined && v !== null) {
                    url += key[i] + "=" + v + "&";
                }
            }
        }
        return url.substring(0, url.length - 1);
    },
    /**
     * 获取当前页面url后面的参数值
     * @param location
     * @returns {{}}
     */
    findParams: function (location) {
        // 获取页面的url地址
        var url = location.href;
        var paraString = url.substring(url.indexOf("?") + 1, url.length).split("&");
        var paraObj = {};
        for (var i = 0; i < paraString.length; i++) {
            var j = paraString[i];
            paraObj[j.substring(0, j.indexOf("="))] = j.substring(j.indexOf("=") + 1, j.length);
        }
        return paraObj;
    }
};

/**
 * 下载工具
 */
const DownloadUtil = {
    /**
     * 根据url创建表单请求
     * @param url
     * @param params
     */
    urlToForm: function (url, params) {
        // 创建表单
        var form = document.createElement("form");
        form.setAttribute("method", "post");
        form.setAttribute("action", url);
        // 添加数据
        Object.keys(params).forEach(function (key) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);
            form.appendChild(hiddenField);
        });
        // 把表单添加到body里面
        document.body.appendChild(form);
        // 提交
        form.submit();
        // 移除临时创建的form
        document.body.removeChild(form);
    },
    /**
     * 根据文件路径下载数据（存在跨域问题）
     * @param filePath
     * @param fileName
     */
    downloadByFilePath: function (filePath, fileName) {
        // 这是传统的下载方式
        const downloadFileA = document.createElement('a');
        document.body.append(downloadFileA);
        downloadFileA.href = filePath;// 下载路径
        downloadFileA.download = fileName;// 文件名
        // 超链接 target="_blank" 要增加 rel="noopener noreferrer" 来堵住钓鱼安全漏洞。
        // 如果你在链接上使用 target="_blank"属性，并且不加上rel="noopener"属性，那么你就让用户暴露在一个非常简单的钓鱼攻击之下。(摘要)
        downloadFileA.rel = 'noopener noreferrer';
        downloadFileA.click();
        document.body.removeChild(downloadFileA);
    },
    /**
     * 根据文件路径下载数据(防止图片视频被游览器直接打开)
     * @param filePath
     * @param fileName
     */
    downloadByFilePathByBlob: async function(filePath, fileName) {
        try {
            const response = await fetch(filePath, { mode: 'no-cors' });
            const blob = await response.blob();
            const downloadFileA = document.createElement('a');
            const url = URL.createObjectURL(blob);
            downloadFileA.href = url;
            downloadFileA.download = fileName;
            downloadFileA.rel = 'noopener noreferrer';
            document.body.appendChild(downloadFileA);
            downloadFileA.click();
            document.body.removeChild(downloadFileA);
            URL.revokeObjectURL(url);
        } catch (error) {
            console.error('下载文件出错:', error);
        }
    },
    /**
     * 打开窗口下载
     * @param url
     * @param params
     */
    windowDownload: function (url, params) {
        window.open(UrlUtil.splicingParams(url, params));
    },

    /**
     * 根据url下载文件（可以跨域）
     * @param url 文件url
     */
    downloadUrlFile: function (url) {
        var thas = this;
        url = url.replace(/\\/g, '/');
        const xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.responseType = 'blob';
        //xhr.setRequestHeader('Authorization', 'Basic a2VybWl0Omtlcm1pdA==');
        xhr.onload = () => {
            if (xhr.status === 200) {
                // 获取文件blob数据并保存
                var fileName = thas.getFileName(url);
                thas.saveAs(xhr.response, fileName);
            }
        };
        xhr.send();
    },

    /**
     * blob数据文件到本地
     * @param data 文件的blob数据
     * @param name 文件名
     */
    saveAs: function (data, name) {
        var urlObject = window.URL || window.webkitURL || window;
        var export_blob = new Blob([data]);
        var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
        save_link.href = urlObject.createObjectURL(export_blob);
        save_link.download = name;
        save_link.click();
    },

    /**
     * 根据文件url获取文件名
     * @param url 文件url
     */
    getFileName: function (url) {
        var num = url.lastIndexOf('/') + 1
        var fileName = url.substring(num)
        //把参数和文件名分割开
        fileName = decodeURI(fileName.split("?")[0]);
        return fileName;
    },

    /**
     * 下载图片（可以跨域）
     * @param imgsrc 下载图片地址
     * @param name 图片名
     */
    downloadIamge: function (imgsrc, name) {
        let image = new Image();
        // 解决跨域 Canvas 污染问题
        image.setAttribute("crossOrigin", "anonymous");
        image.onload = function () {
            let canvas = document.createElement("canvas");
            canvas.width = image.width;
            canvas.height = image.height;
            let context = canvas.getContext("2d");
            context.drawImage(image, 0, 0, image.width, image.height);
            let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
            let a = document.createElement("a"); // 生成一个a元素
            let event = new MouseEvent("click"); // 创建一个单击事件
            a.download = name || "photo"; // 设置图片名称
            a.href = url; // 将生成的URL设置为a.href属性
            a.dispatchEvent(event); // 触发a的单击事件
        };
        image.src = imgsrc;
    },

    /**
     * 下载Blob类型数据
     * @param imgName
     * @param blob
     */
    downloadBlob(imgName, blob) {
        // 创建a标签，添加href属性
        var triggerDownload = $("<a>").attr("href",
            // 创建对象 URL,添加download属性，附加到body上，并添加点击事件
            URL.createObjectURL(blob)).attr("download", imgName).appendTo("body").on("click"
            , function () {
                // navigator.msSaveBlob方法允许用户在客户端上保存文件，方法如同从 Internet 下载文件
                if (navigator.msSaveBlob) {
                    return navigator.msSaveBlob(blob, imgName);
                }
            });
        // 触发事件
        triggerDownload[0].click();
        // 删除标签
        triggerDownload.remove();
    },
    /**
     * 根据Base64下载数据
     * @param url
     */
    downloadImageByBase64(url, fileName) {
        let link = document.createElement("a");
        link.href = url;
        link.setAttribute("download", fileName);
        link.click();
    },
    /**
     * 下载 Ecahrts 图片
     *     eg: downloadEcahrtsImage(ecahrts.getDataURL(),'name')
     * @param url
     * @param name
     */
    downloadEcahrtsImage(url, name) {
        // 生成一个a元素
        const a = document.createElement('a');
        // 设置图片名称
        a.download = name || 'photo';
        // 将生成的URL设置为a.href属性
        a.href = url;
        // 触发a的单击事件
        a.click();
    },
    /**
     * ajax下载文件并命名
     * @param params
     * @param url
     * @param fileName
     */
    downloadAjax: function (params, url, fileName) {
        const layerIdx = layer.msg("正在导出，请稍候...", {
            icon: 16,
            time: 1000,
            shade: 0.2
        });
        $.ajax({
            type: "GET",
            url: url,
            data: params,
            dataType: 'binary',
            xhrFields: {responseType: "blob"},
            contentType: "application/octet-stream",
            success: function (res) {
                // res 为二进制流
                console.log("成功", res)
                let blob = new Blob([res])
                let da = document.createElement('a')
                da.href = URL.createObjectURL(blob);
                da.setAttribute("download", fileName);
                da.click();
                URL.revokeObjectURL(da.href);
            },
            complete: function (XMLHttpRequest, status) {
                // console.log(XMLHttpRequest,status)
            },
            beforeSend: function () {
                layer.msg("正在导出，请稍候...", {
                    icon: 16,
                    time: 1000,
                    shade: 0.2
                });
            }
        }).always(function () {
            layer.close(layerIdx);
        });
    }

};

/**
 * fetch 是一种 HTTP 数据请求的方式
 */
const FetchUtil = {
    // get请求
    getRequest: function (url,callback){
        // 处理原始的 HTTP 响应，并将响应对象转换为 JSON
        fetch(url).then((response) => {
                if(response.ok){
                    // 读取json文件对象
                    response.json().then((json) => {
                        callback(json)
                    })
                }else {
                    throw new Error(`HTTP error! status: ${response.status}`)
                }
            })
            // 将处理 JSON 数据，并将其输出到控制台
            .then(data => console.log('data:',data))
            // 捕获错误
            .catch((error) => console.error('Error:', error));
    },
    // post请求
    postRequest: function (url,callback){
        fetch(new Request(url,{method:'POST'}))
            .then((resp)=>{resp.json().then((json) => {callback(json)})})
    }
};